package com.cskaoyan.javase.oop1._2reference;
/**
 * 重新认识引用数据类型
 * 我们第一次认识和了解引用数据类型是在数组这一章节，我们通过JVM内存模型图和数组的初始化过程，知道：
 * 一个引用数据类型变量，分为两个部分：
 *      1.在栈上创建引用，它是一个局部变量。
 *      2.在堆上开辟空间，创建对象。
 * 栈上的引用通过存储堆上对象的地址和对象产生联系。
 * 对象是引用数据类型的实质，但我们只能通过栈上引用间接访问堆上对象。
 * 现在，我们已经学习过对象与类的知识点了，是时候进一步或者换一个角度去了解引用数据类型了。
 *
 * 我们用数据类型的定义来统一基本数据类型和引用数据类型的概念
 * 数据类型的定义: 一组合法的数据的集合,和基于这组合法数组的操作的集合
 *      说白了,数据类型 = 数据 + 操作
 *
 * 在上一节类的定义中，类中的成员包括：
 * 成员变量
 * 成员方法
 * 成员变量本质上就是数据，成员方法本质上就是操作，那么假设做以下类比：
 * 数据的集合： 类中成员变量的集合
 * 操作的集合： 类中成员方法的集合
 *
 * 于是，就可以做出以下总结：
 * 一个类的定义，实际上就是定义了一种全新的数据类型，一种自定义的数据类型。
 * 这种完全不同于基本数据类型的数据类型，我们称之为"引用数据类型"。
 * 注：当然引用数据类型不仅仅包括类，但大体上上述说法是没问题的。
 *
 * 类这种引用数据类型,不同于基本数据类型,JVM在利用类创建对象或者做其他任何操作时,一开始是不了解这个类型的
 * 没有办法做任何操作
 * 所以在对某个类型做任何操作之前,需要JVM先了解认识该类型,这个过程,在Java中称之为"类加载"
 *
 * 关于类加载:
 *      1.类加载会在后面课程中,详细学习,这里我们先做基本的了解.
 *      2.类加载是通过I/O流的形式将某个类的字节码文件读取进方法区,经过一系列的过程,从而实现认识了解该类型
 *
 *      思考:
 *      1.类加载和创建对象,它们应该谁先进行? 很显然是类加载,因为只有类加载后,才认识类型,可以创建对象
 *      2.如果我要创建一个类的对象,这个类会不会类加载? 肯定会,而且是先类加载,再创建对象
 *      3.类加载是通过I/O流的形式读取文件进行的,I/O的效率是很低的,所以为了避免类加载影响程序的运行效率
 *          所以类加载是当必须使用某个类时,才会进行类加载
 *          类加载是懒加载的,只有当迫不得已需要类加载时,JVM才会类加载一个类.
 *          在Java中,我们把一定会触发该类类加载的场景,称之为"类加载的时机"
 *          类加载的时机目前学过两种:
 *                  1.new对象,触发该类类加载
 *                  2.启动某个类的main方法,触发该类类加载
 *          注: 代码运行碰到类加载的时机,会先类加载这个类,再去做这个操作!
 *      4.某个类在程序的运行期间,已经通过某种手段触发了类加载,请问之后还会再触发一次类加载吗?
 *          不会
 *          在一次程序的运行的期间,某个类要么不类加载,要么至多类加载一次,不管有多少触发类加载的场景!!
 *
 * @since 11:19
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    // 比如启动main方法触发Demo类的类加载,一定是要先类加载Demo类,然后main方法才能启动!!!
    public static void main(String[] args) {
        // 创建Student类对象,触发Student类的类加载, 需要先类加载Student,再创建对象!!
        Student s = new Student();

        // 这里还会类加载Demo吗?
        /*
            Demo类已经因为启动main方法,进行了一次类加载
            不会再因为其他手段,而触发类加载了
            这里就可以直接创建Demo类对象,无需类加载!!
         */
        Demo d = new Demo();
    }
}
class Student{}